package util

import (
	"io/ioutil"
	"os"
	"path"
	"strings"
)

const (
	shim = "shim.Start"
)

// 遍历contractPath下所有的go文件,检查是否含有protoGo和shim
func CheckContractIs210(contractPath string) (bool, error) {
	var err error
	var fds []os.FileInfo
	if _, err = os.Stat(contractPath); err != nil {
		return false, err
	}
	if fds, err = ioutil.ReadDir(contractPath); err != nil {
		return false, err
	}
	for _, fd := range fds {
		srcFilePath := path.Join(contractPath, fd.Name())
		if fd.IsDir() {
			is210, subErr := CheckContractIs210(srcFilePath)
			if subErr != nil {
				return false, subErr
			}
			if is210 {
				return is210, nil
			}
		} else {
			is210, checkErr := checkFileIs210(srcFilePath)
			if checkErr != nil {
				return false, checkErr
			}
			if is210 {
				return is210, nil
			}
		}
	}
	return false, nil
}

func checkFileIs210(filePath string) (bool, error) {
	// 跳过非go文件
	if !strings.HasSuffix(filePath, ".go") {
		return false, nil
	}
	contents, contentsErr := ioutil.ReadFile(filePath)
	if contentsErr != nil {
		return false, contentsErr
	}
	contentStr := string(contents)
	return strings.Contains(contentStr, shim), nil
}

var (
	chainMakerPackages = []string{"chainmaker/pb/protogo", "chainmaker/logger", "chainmaker/sandbox",
		"chainmaker/sdk"}
)

func CheckSrcImportChainmakerPackages(contractPath string) (bool, error) {
	var err error
	var fds []os.FileInfo
	if _, err = os.Stat(contractPath); err != nil {
		return false, err
	}
	if fds, err = ioutil.ReadDir(contractPath); err != nil {
		return false, err
	}
	for _, fd := range fds {
		srcFilePath := path.Join(contractPath, fd.Name())
		if fd.IsDir() {
			imported, subErr := CheckSrcImportChainmakerPackages(srcFilePath)
			if subErr != nil {
				return false, subErr
			}
			if imported {
				return imported, nil
			}
		} else {
			imported, checkErr := checkFileHasImportChainmakerPackages(srcFilePath)
			if checkErr != nil {
				return false, checkErr
			}
			if imported {
				return imported, nil
			}
		}
	}
	return false, nil
}

func checkFileHasImportChainmakerPackages(filePath string) (bool, error) {
	// 跳过非go文件
	if !strings.HasSuffix(filePath, ".go") {
		return false, nil
	}
	contents, contentsErr := ioutil.ReadFile(filePath)
	if contentsErr != nil {
		return false, contentsErr
	}
	contentStr := string(contents)
	for _, tmpP := range chainMakerPackages {
		if strings.Contains(contentStr, tmpP) {
			return true, nil
		}
	}
	return false, nil
}
